<?php

/**
 * 任务派发类
 * @author jeff liu
 */
class Dispatcher
{

    /**
     * 任务派遣方法
     * @author jeff liu
     * @return boolean
     */
    public static function dispatch()
    {
        /**
         * 解析url
         */
        self::parseRequest();

        /**
         * 当前需要访问的app
         * @var string
         */
        $app = isset($_GET['app']) && !empty($_GET['app']) ? $_GET['app'] : DEFAULT_APP;

        /**
         * 当前访问的控制器
         * @var string
         */
        $ctl = isset($_GET['ctl']) && !empty($_GET['ctl']) ? $_GET['ctl'] : DEFAULT_CTL;

        /**
         * 当前访问的action
         * @var string
         */
        $act = isset($_GET['act']) && !empty($_GET['act']) ? $_GET['act'] : DEFAULT_ACT;

        /**
         * 当前访问的project
         * @var string
         */
        $project = defined('PROJECT') ? PROJECT : 'frontend';
        define('PROJECT_ROOT_PATH', ROOT_PATH . '/' . $project);

        /**
         * 导入必须的基础控制器
         */
        Importer::importFile($project, 'ctl.php', PROJECT_ROOT_PATH);


        /**
         * 导入当前访问的控制器
         */
        Importer::importFile($app . '.controllers.' . $ctl, 'ctl.php', PROJECT_ROOT_PATH);

        $ctl_class_name = ucfirst($ctl) . 'Ctl';
        $controller = new $ctl_class_name();
        $args = $_GET;
        if (method_exists($controller, $act) && substr($act, 0, 1) != '_') {
            $args['act'] = $act;
            call_user_func(array($controller, 'doAction'), $args);
        } else {
            trigger_error('controller ' . get_class($controller) . 'do not exists method ' . $act, E_USER_ERROR);
            return false;
        }
    }

    /**
     * 解析url
     * @author jeff liu
     */
    public static function parseRequest()
    {
        $query = $_SERVER["QUERY_STRING"];

        $request_uri = $_SERVER['REQUEST_URI'];
        if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
            $request_uri = $_SERVER['HTTP_X_REWRITE_URL'] ? $_SERVER['HTTP_X_REWRITE_URL'] : $request_uri;
        }

        $get = null; //存放放在url中的参数(?之后的部分)
        if ($p = strpos($query, '?')) { //url中还有参数
            $get = substr($query, $p + 1); //?后面的东西
            $query = substr($query, 0, $p); //$query ？之前的东西
        } else {
            $p = parse_url($request_uri);
            if (isset($p['query'])) {
                $get = $p['query'];
            }
        }
        if ($get != $query) { //????????????
            parse_str($get, $get);
            $_GET = array_merge($_GET, (array)$get);
        }

        if (!isset($_GET['ctl'])) {
            $_GET['ctl'] = 'default';
        }
        if (!isset($_GET['act'])) {
            $_GET['act'] = 'index';
        }
    }


    /**
     * 派遣任务前需要执行的动作
     * @author jeff liu
     * @param string $ctl
     * @param string $act
     * @param string $args
     */
    private static function preDispatch(&$ctl = null, $act = null, $args = array())
    {

    }


    /**
     * 派遣任务后需要执行的动作
     * @author jeff liu
     * @param string $ctl
     * @param string $act
     * @param string $args
     */
    private static function postDispatch(&$ctl = null, $act = null, $args = array())
    {

    }

}